package org.subatu.orm.query.table;


import org.springframework.util.Assert;
import org.subatu.orm.query.base.CondEnum;
import org.subatu.orm.util.ChkUtil;

import java.util.List;
import java.util.Map;

/**
 * 条件列
 */
public class CondColumn {

    // 关系
    private CondEnum relationEnum;


    private boolean isCheck;
    // 哪个列
    private QueryColumn queryColumn;
    // 条件
    private CondEnum condEnum;
    // 值
    private Object value;

    // 单条件构造
    public CondColumn(CondEnum relationEnum) {
        boolean in = ChkUtil.in(relationEnum, CondEnum.and, CondEnum.or, CondEnum.boxL, CondEnum.boxR);
        Assert.isTrue(in, "错误的关系表达式 : " + relationEnum);
        this.relationEnum = relationEnum;
    }

    // 多条件构造
    public CondColumn(boolean isCheck, QueryColumn queryColumn, CondEnum condEnum, Object value) {
        this.isCheck = isCheck;
        this.queryColumn = queryColumn;
        this.condEnum = condEnum;
        this.value = value;
    }

    public CondColumn(String condSql) {
        this.condSql = condSql;
    }

    // 最终生成的 条件 sql
    private String condSql;


    // 编译条件为 sql
    public String buildCondSql(Map<String, String> tableAliasMap, List<Object> valueList) {
        if (ChkUtil.isNotNull(condSql)) {
            return condSql;
        }
        // 1. 关系 直接压栈
        if (relationEnum != null) {
            return relationEnum.getValue() + ' ';
        }
        if (isCheck == false) {
            return "";
        }
        // 2. 非关系生成条件
        String sql = "and ";// 默认条件为 and
        String tableName = queryColumn.getTable().getTableName();
        sql += queryColumn.buildCondSql(tableAliasMap.get(tableName));
        sql += ' ' + condEnum.getValue() + ' ';

        if (condEnum.notValue()) {
            // 直接返回,什么也不做
        } else if (value instanceof QueryColumn) {
            QueryColumn valueCoumn = (QueryColumn) value;
            sql += valueCoumn.buildCondSql(tableAliasMap.get(valueCoumn.getTable().getTableName()));
        } else {
            sql += '?';
            valueList.add(wrapValue(value));
        }
        sql += ' ';

        return sql;
    }

    // 根据条件 包裹 ? 对应 value值
    private Object wrapValue(Object value) {
        if (condEnum == CondEnum.likeL) {
            return value + "%";
        } else if (condEnum == CondEnum.likeR) {
            return "%" + value;
        } else if (condEnum == CondEnum.like) {
            return "%" + value + "%";
        } else if (ChkUtil.in(condEnum, CondEnum.in, CondEnum.notIn)) {
            return value;
        } else {
            return value;
        }
    }

}
